﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using DbTaglio.SvcLayer.DbTaglioService;
using System.ServiceModel.Description;
using System.Web.UI.WebControls;

namespace DbTaglio.SvcLayer
{
    public class WcfBase
    {
        //"http://sisc01-test.sisc.sopra.colt:8080/Service1.svc";
        public static  string UrlServizio1 = "http://localhost:8081/service1.svc";

        public string User { get; set; }
        public String Pwd { get; set; }
        public Boolean Impersona { get; set; }

 
        public ChannelFactory<IService1> Channelfactory { get; set; }

        IService1 _servizio1 = null; 
        public IService1 Proxy {
            get { if (_servizio1 == null) getChannel();
                    return _servizio1; }              
            set{_servizio1 = value  ;} }


        public WcfBase(string pUserName, string pPwd, bool pImpersonate = true)
        {
            User = pUserName;
            Pwd = pPwd;
            Impersona = pImpersonate;

            //UrlServizio1 = "http://sisc01-test.sisc.sopra.colt:8080/Service1.svc";

        }

       
        public  IService1 getChannel()
        {
            if (Channelfactory == null)
            {
                //WSHttpBinding serviceBinding = new WSHttpBinding();
                //serviceBinding.Security.Mode = SecurityMode.TransportWithMessageCredential;

                Uri serviceUri = new Uri(UrlServizio1);

                BasicHttpBinding serviceBinding = new BasicHttpBinding();
                serviceBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
                serviceBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
                serviceBinding.CloseTimeout = new TimeSpan(0, 30, 0);
                serviceBinding.MaxReceivedMessageSize = 2147483646;
                serviceBinding.ReceiveTimeout = new TimeSpan(0, 2, 0);
                //serviceBinding.UseDefaultWebProxy = true;
                serviceBinding.BypassProxyOnLocal = true;

                EndpointAddress endPoint = new EndpointAddress(serviceUri);
                Channelfactory = new ChannelFactory<IService1>(serviceBinding, endPoint);


                //IService1 servizio 
                Proxy = Channelfactory.CreateChannel();
                //channelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
                //channelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
 
            }

            var credentialBehaviour = Channelfactory.Endpoint.Behaviors.Find<ClientCredentials>();

            if (string.IsNullOrEmpty(User))
            {
                credentialBehaviour.Windows.ClientCredential.UserName = User;// "Diego";
                credentialBehaviour.Windows.ClientCredential.UserName = Pwd;// "Pa$$w0rd1";
            }

            if (Impersona)
                credentialBehaviour.Windows.AllowedImpersonationLevel =
                    System.Security.Principal.TokenImpersonationLevel.Impersonation;


            if(Channelfactory.State !=  CommunicationState.Opened) Channelfactory.Open();
             
            return Proxy;

        }


        public void CloseAll(bool pSetNull)
        {
            if (Channelfactory != null)
                if (Channelfactory.State != CommunicationState.Closed) Channelfactory.Close();

            if (pSetNull) Channelfactory = null;

            Proxy = null;
        }


        public RetData<string> tryHelloWcf()
        {
            try
            {

                string htp = "http://localhost:8081/service1.svc";
                Uri serviceUri = new Uri(UrlServizio1);

                BasicHttpBinding serviceBinding = new BasicHttpBinding();
                //WSHttpBinding serviceBinding = new WSHttpBinding();

                serviceBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
                serviceBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

                EndpointAddress endPoint = new EndpointAddress(serviceUri);

                ChannelFactory<IService1> channelFactory =
                     new ChannelFactory<IService1>(serviceBinding, endPoint);


                IService1 servizio = channelFactory.CreateChannel();
                //channelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
                //channelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
                var credentialBehaviour = channelFactory.Endpoint.Behaviors.Find<ClientCredentials>();
                credentialBehaviour.Windows.ClientCredential.UserName = User;// "Diego";
                credentialBehaviour.Windows.ClientCredential.UserName = Pwd;// "Pa$$w0rd1";

                credentialBehaviour.Windows.AllowedImpersonationLevel =
                    System.Security.Principal.TokenImpersonationLevel.Impersonation;

                try
                {
                    string ret = servizio.HelloWCF();
                    return new RetData<string>(ret);
                }
                catch (Exception ex)
                {
                    return new RetData<string>(ex);
                }
                finally { channelFactory.Close(); } 

            }
            catch (Exception ex)
            {
                return new RetData<string>(ex);
            }


        }//fM



        internal RetData<R> Execute2<T,T2, R>(Func<T,T2,R> pFunc, T pArg, T2 pArg2)
        {
            try
            {

                var ret = pFunc.Invoke(pArg,pArg2);
                return new RetData<R>(ret);
            }
            catch (Exception ex)
            {
                return new RetData<R>(ex);
            }
        }

        internal RetData<R> Execute<T, R>(Func<T, R> pFunc, T pArg)
        {
            try
            {

                var ret = pFunc.Invoke(pArg);
                return new RetData<R>(ret);
            }
            catch (Exception ex)
            {
                 return new RetData<R>(ex);
            }
        }


        internal RetData<R> Execute<R>(Func<R> pFunc)
        {
            try
            {
                var ret = pFunc.Invoke();
                return new RetData<R>(ret);
            }
            catch (Exception ex)
            {
                return new RetData<R>(ex);
            }
        }



     

    }//fC
}
